/* 
  通过nodejs 中的  
  HTTP模块、URL模块、fs模块、Path模块
  来构建静态资源服务器
*/

const http = require('http')
const fs = require('fs')
const path = require('path')
const url = require('url')
const mimer = require('./extends/mimer.js')
const router = require('./router/router.js')
const config = global.config
const PORT = config.PORT || 8001

// 启动
http.createServer((req, res) => {
  let lpath = (req.path || '').toLowerCase()
  let method = req.method.toLowerCase()

  // 允许的请求头
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,HEAD,OPTIONS')
  let headers = config.headers || {}
  for (let key in headers) {
    res.setHeader(key, headers[key])
  }

  // 允许跨域访问
  if (config.isCrossOrigin) {
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.setHeader("Access-Control-Allow-Credentials", "true")
  }

  // 动态origin
  if (String(config.isDynamicOrigin) === '1' || String(config.isDynamicOrigin) === 'true') {
    res.setHeader("Access-Control-Allow-Origin", req.headers.origin || '*')
  }

  if (/options|head/i.test(method)) {
    res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' })
    res.write('OK')
    res.end() // 结束响应
    return true
  }

  var pathname = url.parse(req.url).pathname   // 通过url.parse()直接获取请求的数据路径
  let query = url.parse(req.url).query
  pathname = pathname.replace(/\.\.\//g, '').replace(/\/\//g, '/')
  // 过滤请求
  if (pathname === '/') {
    let defaultIndex = config.defaultIndex || '/pages/index.html'
    pathname = defaultIndex // 默认首页
  } else if (pathname === '/favicon.ico') {
    pathname = '/favicon.ico' // 默认图标
  }

  // 服务请求
  if (router.matchRoute(pathname, method)) {
    let route = router.matchRoute(pathname, method)
    let defer = router.run(route, req, res)
    Promise.resolve(defer).then(result => {
      if (result && result.status) {
        let isObject = Object.prototype.toString.call(result) === '[object Object]' || /^\s*(\[|\{})/.test(result)
        let contentType = isObject ? 'application/json;charset="utf-8"' : 'text/html;charset="utf-8"'
        res.writeHead(result.status, { 'Content-Type': contentType })
        res.write(isObject ? JSON.stringify(result) : (result || ''))
        res.end() // 结束响应
      }
    }).catch((e) => {
      s500(res)
      console.log(e)
    })
    return true
  }
  // 普通请求
  else {
    // 请求目录验证
    let accessDirs = Array.isArray(config.accessDirs) ? config.accessDirs : []
    let repNode = accessDirs.find(item => {
      let path = item.path || item
      return String(pathname).toLowerCase().indexOf(String(path).toLowerCase()) > -1
    })
    let dir = path.dirname(__filename) + pathname
    // 目录转换
    if (repNode) {
      let rpath = pathname
      let replace = repNode.replace
      // 路径转换
      if (Array.isArray(replace)) {
        replace.forEach(item => {
          rpath = rpath.replace(item.match, item.replace)
        })
      } else if (typeof replace === 'string') {
        rpath = pathname.replace(repNode.path, repNode.replace)
      }
      // 参数转换为路径
      let rquery = repNode.query
      if (Array.isArray(rquery)) {
        rquery.forEach(item => {
          if (item.match.test(query)) {
            let value = item.match.exec(query)[0]
            value = value.replace(item.match, item.replace)
            rpath += item.wrap !== false ? '/' + value : value
          }
        })
      }
      pathname = rpath
      dir = path.dirname(__filename) + rpath
    }
    // 无转换，则默认访问www根目录
    else {
      let accessRootDir = config.accessRootDir || ''
      if (!/^\/pages/i.test(pathname)) {
        pathname = (accessRootDir + '/' + pathname).replace(/\.\.\//g, '').replace(/\/\//g, '/')
        dir = path.dirname(__filename) + pathname
      }
    }
    // 读取指定文件
    if (fs.existsSync(dir)) {
      fs.readFile(path.resolve(dir), (err, result) => {
        // 文件未找到
        if (err) {
          s404(res)
        }
        // 正常输出文件
        else {
          // 获取文件的后缀名，根据不同的后缀名返回不同的信息
          var extname = path.extname(pathname)
          // 响应头
          var mime = mimer.getMime(extname) // 获取文件类型
          res.writeHead(200, { 'Content-Type': '' + mime + ';charset="utf-8"' })
          res.write(result)
          res.end() // 结束响应
        }
      })
    } else {
      s404(res)
    }
  }
}).listen(PORT, '0.0.0.0', () => {
  console.log('服务端->http://127.0.0.1:' + PORT)
})

// 401服务
function s401 (res) {
  fs.readFile('./pages/404.html', (error, data) => {
    // 404文件读取失败
    if (error) {
      s500(res)
      console.log(error)
      return false
    }
    res.writeHead(401, { 'Content-Type': 'text/html;charset="utf-8"' })
    res.write(data)
    res.end() // 结束响应
  })
}

// 404服务
function s404 (res) {
  fs.readFile('./pages/404.html', (error, data) => {
    // 404文件读取失败
    if (error) {
      s500(res)
      console.log(error)
      return false
    }
    res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' })
    res.write(data)
    res.end() // 结束响应
  })
}

// 500服务
function s500 (res) {
  res.writeHead(500, { 'Content-Type': 'text/html;charset="utf-8"' })
  res.write('Service 500 Error')
  res.end() // 结束响应
}
